perm filename PINTRP.OLD[PNT,HE]1 blob
sn#467714 filedate 1979-08-19 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00019 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 data trasnfer macros: SNDINT,SNDFP
C00004 00003 temporary resting place for routines displaced from INTERP.PAL[AL,HE]
C00006 00004 data transfer : PUSHINTI,ARTVAL,RTVAL,AGTVAL,RTARR,FRVAL
C00017 00005 RTLEVS - returns leveloffset info of stack in integer buffer
C00019 00006 PAFFIX,PUNFIX
C00024 00007 display: DISVT05
C00025 00008 PSPROUT: used with COBEGIN
C00027 00009 RCASE: used with CASE
C00029 00010 relative jumps: RFRCHK,RJMP,RJMPC
C00032 00011 printing routines: RPRINT,PRVAL,PRINTI
C00037 00012 supplementary motions: pmove,tadrive,tddrive,gather,rforce,setstf
C00041 00013 supplementary functions: uparrow,dwnarrow,alpha,dollar,swap,vneg,vsmul,ftof
C00045 00014 functions: sqrt,sin,cos,asin,acos,tan,atan2,log,exp
C00046 00015 armreach- can arm reach here?
C00048 00016 procedure handling: GTBLK
C00050 00017 more stack ops: gtint,gvals,chngs
C00052 00018 components of data types: CHCMP,GTCMP
C00055 00019 return from POINTY : pdone
C00056 ENDMK
C⊗;
COMMENT ⊗ data trasnfer macros: SNDINT,SNDFP
⊗
.MACRO SNDINT X
MOV X,@INTPTR
ADD #2,INTPTR
.ENDM
.MACRO SNDFP X
STF X,@FPPTR
ADD #4,FPPTR
.ENDM
.MACRO SNDFIN X
STCFI X,@INTPTR
ADD #2,INTPTR
.ENDM
;; routine for transferring a block of fp data from 11 to 10
;; R0 has address of data, R1 has # FP numbers to transfer
;; R0,R1,AC0 are garbaged
FTAPE: TST R1
BEQ 2$
PUSH <R2>
MOV FPPTR,R2
1$: LDF (R0)+,AC0
STF AC0,(R2)+
SOB R1,1$
MOV R2,FPPTR
POP <R2>
2$: RTS PC
; temporary resting place for routines displaced from INTERP.PAL[AL,HE]
COMMENT ⊗
COPY: FETCH R0 ;Pick up argument.
COPY0: ADD R0,R0 ;Double R0 to make it in bytes
ADD R3,R0 ;R0 ← LOC[stack element to be copied to top]
MOV (R0),-(R3) ;Copy it onto top of stack.
CCC ;Clear condition code.
RTS PC ;Done
⊗;
COMMENT ⊗
PUSHSCI:
; The argument is a (2 word) floating point number. Make a scalar out of it and
; push that scalar onto stack.
LDF @IPC(R4),AC0;get the floating point arg
ADD #4,IPC(R4) ;Bump IPC--TWO TIMES !
JSR PC,NOCMP
JSR PC,GETSCA ;R0 ← -(R3) ← LOC[new scalar block]
STF AC0,@(R3) ;Store result
JSR PC,YESCMP
CCC ;Clear condition code.
RTS PC ;Done
⊗;
COMMENT ⊗ data transfer : PUSHINTI,ARTVAL,RTVAL,AGTVAL,RTARR,FRVAL
routines to facilitate data transfer to POINTY interface
XX is scalar index; Y is leveloffset of array element
AGTVAL XX,Y = PUSHINTI XX; GTVAL Y
ACHNGE XX,Y = PUSHINTI XX; CHNGE Y
ARTVAL XX,Y = AGTVAL XX,Y; RTVAL
RTARR Y returns #elements and value of array offset Y
RTVAL is used to transfer the top element of stack to the return buffer
⊗;
PUSHINTI:
; The argument is an integer. Make a scalar out of it and
; push that scalar onto stack.
FETCH R0
LDCIF R0,AC0 ;convert to real
JSR PC,NOCMP
JSR PC,GETSCA ;R0 ← -(R3) ← LOC[new scalar block]
STF AC0,@(R3) ;Store result
JSR PC,YESCMP
CCC ;Clear condition code.
RTS PC ;Done
AGTVAL: JSR PC,PUSHINTI ; get value of index to array
JMP GTVAL ; now get the offset of the array
CCHNGE: CLR R0
JSR PC,COPY0 ; copy value of top element in stack
JMP CHNGE ; now do the assignment
CACHNG: CLR R0
JSR PC,COPY0 ; copy value of top element in stack
ACHNGE: JSR PC,PUSHINTI ; get value of index to array
JMP CHNGE ; now update value of the array
CRTVAL: MOV (R3),R0 ; return top of stack without popping
JMP RTVAL0
FRVAL: FETCH <R0> ; get offset
FRVAL0: JSR PC,GETARG ; R0←LOC[environment entry]
BIT #HDRTYP,(R0) ; check header exists
BNE 1$
JSR PC,MFRAME ; make frame header
1$: MOV 2(R0),R0 ; R0←LOC[frame header]
PUSH <R0> ; save R0
ADD #CALCS,R0 ; R0←LOC[beginning of calculator list]
2$: MOV (R0),R0 ; R0←LOC[next calcualtor to check]
BEQ 6$ ; Make sure there is something there
BIT #AFXTYP,TYPE(R0); Make sure it is an affixment
BEQ 2$
BIT #FRAME2,TYPE(R0); Check if second frame in affixment
BNE 2$ ; If not, go check the next calculator
3$: BIT #EXPTRN,TYPE(R0); Is it an explicit trans?
BEQ 4$
MOV @TRANS(R0),R0 ; R0←LOC[trans]
BR 5$
4$: MOV TRANS(R0),R0 ; implicit trans
5$: POP <R1> ; get SP to correct state
JMP PC,RTVAL0 ; retrun from RTVAL0
6$: POP <R0>
JSR PC,NOCMP
CALL GETVAL,<R0> ; R0←Value
JSR PC,YESCMP
JMP PC,RTVAL0 ; return from RTVAL0
comment ⊗
RTARR: FETCH R0 ; get offset of the array we are interested in
PUSH <R2> ; save R2
JSR PC,GETENV ; get environment pointer in R0
MOV 2(R0),R2 ; R2←LOC[array header]
MOV (R2)+,R0 ; R0←# of dimensions of array
CLR -(SP) ; compute number of elements in array
1$: MOV (R2)+,R1 ; R1←(ub[i]- lb[i])*mult[i]
SUB (R2)+,R1 ;
INC R1 ; add 1
MUL (R2)+,R1 ;
ADD R1,(SP) ; and add it to elements so far
SOB R0,1$ ; repeat for all the dimensions
MOV (SP)+,R1 ; R1←# of elements in array
SNDINT R1 ; send it back to 10
PUSH <R2> ; save current environment entry
⊗;
RTARR: JSR PC,ARRSIZ ; get array size
; R0←array size, R1←LOC[first env entry]
SNDINT R0
PUSH <R2>
PUSH <R1> ; (SP)←LOC[env entry]
MOV R0,R2 ; R2←#elements
2$: MOV (SP),R0 ; R0←LOC[env entry]
ADD #4,(SP) ; (SP)←next environment entry
JSR PC,GVAL1 ; (R3)←LOC[value cell]
JSR PC,RTVAL ; return the element value
SOB R2,2$
TST (SP)+ ; dont need the value of last push
POP <R2> ; get back the initial value of R2
CCC
RTS PC ; and return
; following routine returns parameter values to the 10 and returns
; the following register values:
; R0←#elements in the array
; R1←LOC[env entry for first element]
RTPARS: FETCH R0 ; get offset of the array we are interested in
SNDINT #XRTPARS ; send back info to 10
SNDINT R0 ; send back arrayoffset number to 10
PUSH <R2> ; save R2
PUSH <INTPTR> ; save location of INTPTR for later use
ADD #2,INTPTR ; increment the value of intptr
JSR PC,GETENV ; get environment pointer in R0
MOV 2(R0),R2 ; R2←LOC[array header]
MOV (R2)+,R0 ; R0←# of dimensions of array
SNDINT R0 ; return # of dimensions
CLR -(SP) ; compute number of elements in array
1$: MOV (R2)+,R1 ; R1←(ub[i]- lb[i])*mult[i]
SNDINT R1 ; return upper bound
SNDINT (R2) ; return lower bound
SUB (R2)+,R1 ;
SNDINT (R2) ; return multiplier
INC R1 ; add 1
MUL (R2)+,R1 ;
ADD R1,(SP) ; and add it to elements so far
SOB R0,1$ ; repeat for all the dimensions
MOV (SP)+,R1 ; R1←# of elements in array
POP <R0>
MOV R1,(R0) ; and send it to the buffer
MOV R1,R0 ; R0←#of elements
MOV R2,R1 ; R1←LOC[env entry of first element]
POP <R2> ; get back the initial value of R2
CCC
RTS PC ; and return
ARRSIZ: FETCH R0 ; takes array offset in R0 and returns
; R0←#elements in array
; R1←LOC[env entry of first element]
ARRSZ0::PUSH <R2>
JSR PC,GETENV ; get environment pointer in R0
MOV 2(R0),R2 ; R2←LOC[array header]
MOV (R2)+,R0 ; R0←#dimensions of array
CLR -(SP) ; compute # of elements in array
1$: MOV (R2)+,R1 ; R1←(UB[i]-LB[i])*mult[i]
SUB (R2)+,R1
INC R1
MUL (R2)+,R1
ADD R1,(SP)
SOB R0,1$
MOV (SP)+,R0
MOV R2,R1
POP <R2>
CCC
RTS PC
SC0: MOV #NILVEC,-(R3)
JMP SNEG
VT0: MOV #NILVEC,-(R3)
JMP VNEG
TR0: PUSH <R2>
MOV #NILTRN,-(R3)
MOV #NILVEC,-(R3)
JSR PC,VNEG
JSR PC,TMAKE
POP <R2>
RTS PC
ARRINI: JSR PC,RTPARS ; get the array size and LOC[env entry first]
PUSH <R2>
MOV R1,-(SP) ; (SP)←LOC[first env entry]
MOV R0,R2
MOV (SP),R0
CMP #SCLTYP,(R0) ; scalar array
BNE 2$
MOV #SC0,1$
BR 4$
2$: CMP #VECTYP,(R0) ;vector array
BNE 3$
MOV #VT0,1$
BR 4$
3$: MOV #TR0,1$ ; niltrans
4$: JSR PC,@1$
MOV (SP),R0
ADD #4,(SP)
JSR PC,CHNG1
SOB R2,4$
TST (SP)+
POP <R2>
CCC
RTS PC
DATA
1$: 0
CODE
ARTVAL: JSR PC,AGTVAL ; get the value of the array element
RTVAL: ; now output the value
MOV (R3)+,R0 ; pop the top element R0←loc[value cell]
RTVAL0: MOV #1,R1 ; counter for counting number of elements
CMPB #TRNID,TAGID(R0) ;A trans?
BEQ 1$
CMPB #VCTID,TAGID(R0) ;A vector?
BEQ 2$
BR 3$ ;Must be a scalar
1$: JSR PC,EULER
MOV #EDAT,R0
MOV #4,R1
2$: ADD #2,R1
3$: LDF (R0)+,AC0 ;load element into AC0
STF AC0,@FPPTR ;move it into return buffer
ADD #4,FPPTR ;update the pointer in the return buffer
SOB R1,3$ ;get the next element
RTS PC
EULER: MOV #EDAT,R1
JSR PC,@LEULER ; now recorrect
MOV #EDAT+14,R1 ; value of THETA
LDF (R1),AC0 ; get value of O computed by euler in armcode
SUBF F90,AC0
STF AC0,(R1)+
LDF (R1),AC0 ; PHI=A+90
ADDF F90,AC0
STF AC0,(R1)
RTS PC
DATA
F90: .FLT2 90.0
F180: .FLT2 180.0
EDAT: .BLKW 30
YHAT: .FLT2 0.0,1.0,0.0,1.0
ZHAT: .FLT2 0.0,0.0,1.0,1.0
CODE
; RTLEVS - returns leveloffset info of stack in integer buffer
RTLEVS:
COMMENT ⊗ Returns offset of top element in the stack if simple variable: if it is
an array, returns the offset and the index sequentially. This does not
affect the stack. R0 and R1 are garbaged.
⊗
MOV R3,R1 ;Use temporary stackpointer
LDF @(R1)+,AC0 ;Get value of top element of stack
STCFI AC0,R0 ;convert into integer and put in R0
MOV R0,@INTPTR ;and store into integer buffer
ADD #2,INTPTR ;and increment integer buffer pointer
PUSH <R1> ;Since GETENV will clobber it
JSR PC,GETENV ;Get the environment pointer in R0
POP <R1> ;TO recover R1
BIT #ARYTYP,(R0) ;Do we have an array to access?
BEQ 10$
PUSH <R2>
MOV 2(R0),R2 ;R2 ← LOC[array header]
MOV (R2)+,R0 ;R0 ← # of dimensions of array
POP <R2>
3$: LDF @(R1)+,AC0 ;Get value of subscript
STCFI AC0,@INTPTR ;Ship it into integer buffer
ADD #2,INTPTR ;update the pointer
SOB R0,3$ ;Do all the subscripts
10$: RTS PC ;Return with R0 and R1 garbaged
; PAFFIX,PUNFIX
PAFFIX:
COMMENT ⊗ AFFIX together the two currently top elements
and return their offsets in the integer buffer.
⊗
SNDINT #XAFFIX ;return affix code
JSR PC,RTLEVS ;return the offset to the 10
JSR PC,GTINT ;Get first frame offset
JSR PC,GETARG ;R0 ← LOC[environment entry]
BIT #HDRTYP,(R0) ;Test access type
BNE 1$
JSR PC,MFRAME ;If necessary make a new frame header
1$: MOV 2(R0),R2 ;R2 ← LOC[first frame header]
JSR PC,RTLEVS ;return the offset to he 10
JSR PC,GTINT ;Get second frame offset
JSR PC,GETARG ;R0 ← LOC[environment entry]
BIT #HDRTYP,(R0) ;Test access type
BNE 2$
JSR PC,MFRAME ;If necessary make a new frame header
2$: MOV 2(R0),R1 ;R1 ← LOC[second frame header]
MOV @(R4),@INTPTR ;Get affixment code and return it
ADD #2,INTPTR ;increment the integer pointer
JMP AFFIX0 ;jump into main affix routine and return from there
PUNFIX:
COMMENT ⊗ return the offsets of the two top elements on the
stack and unfix them
⊗
MOV #2,4$
SNDINT #XUNFIX ;return unfix code
JSR PC,RTLEVS ;return offset to the 10
JSR PC,GTINT ;Get first frame offset
JSR PC,GETARG ;R0 ← LOC[environment entry]
BIT #HDRTYP,(R0) ;Check header exists
BEQ 1$ ; if not quit
MOV 2(R0),R2 ;R2 ← LOC[first frame header]
DEC 4$
1$: JSR PC,RTLEVS ;return offset of the second frame
JSR PC,GTINT ;Get second frame offset
JSR PC,GETARG ;R0 ← LOC[environment entry]
BIT #HDRTYP,(R0) ;Check header exists
BEQ 3$ ; if not quit
MOV 2(R0),R1 ;R1 ← LOC[second frame header]
DEC 4$
2$: BNE 3$
JMP UNFIX0 ; jump into main interpreter routine returning from there
3$: RTS PC ; return from here
DATA
4$: 0
CODE
; display: DISVT05
DISVT05:
FETCH <R0>
TST R0 ;R0=0 → display - R0=1 → nodisplay
BNE 1$ ;go to stop display
MOVB #COFF+30,CURYXAL ;trick display routine to think we are at bottom
MOV #1,FRMDDT ;forces display to update titles
1$: MOV R0,DSPOK
RTS PC
; PSPROUT: used with COBEGIN
PSPROUT:
FETCH <R2> ;R2←# of statements
MOV R2,R0
ASH #1,R0
INC R0
JSR PC,GTFREE
MOV R2,R1 ; R1← # of interpreters to spawn
PUSH <R0> ; save offset of new buffer (1)
PUSH <IPC(R4)> ;save current value of ipc (2)
1$: FETCH <R2> ;get the offset from beginning of sprout
ASH #1,R2 ;get byte offset
ADD (SP),R2 ;add the absolute address
MOV R2,(R0)+ ;stick it into new buffer
FETCH <(R0)+> ;increment the zero - better be zero
SOB R1,1$
FETCH <(R0)+> ; increment one more term, better be zero
TST (SP)+ ; pop value of old ipc (1)
MOV IPC(R4),R1 ; save current IPC value
MOV (SP),IPC(R4); change ipc value to beginning of buffer
PUSH <R1> ; and put old ipc value into the stack (2)
JSR PC,SPROUT ;jump into main AL routine
POP <IPC(R4)> ;restore the ipc value (1)
POP <R0> ;R0←address of buffer (0)
JSR PC,RLFREE ;release the buffer
CCC ;Clear condition code.
RTS PC ;Done
; RCASE: used with CASE
COMMENT ⊗ this routine assumes that the code following is similar to that
following the AL case statement, including range numbers. However, labels
are assumed to be relative to the first label, so that this routine sets
up a new temporary block with the absolute addresses and
then calls AL CASE statement before returning to release the block
⊗;
RCASE: FETCH <R2> ; R2←range
MOV R2,R0
BPL 1$ ; get the absolute value
NEG R0
1$: ADD #2,R0 ; # of labels = R0 + 1, so add 1 for the extra label and
; 1 for the value of R2
PUSH <R0> ; (1)
JSR PC,GTFREE ; get a block of free storage
POP <R1> ; (2)
DEC R1 ; R1← range +1 ,i.e. # of labels
PUSH <R0> ; save address of free storage block(1)
PUSH <IPC(R4)> ; save current IPC(2)
MOV R2,(R0)+ ; 1st word in block=signed range
2$: FETCH <R2>
ASL R2 ; change relative position into bytes
ADD (SP),R2 ; ipc address
MOV R2,(R0)+ ; and push into the block
SOB R1,2$ ; do for all labels
TST (SP)+ ; pop top element, dont need address anymore(1)
MOV (SP),IPC(R4); put address of this new auxilliary block of labels into ipc
JSR PC,CASE ; and jump into AL's case statement
POP <R0> ; now go release the space(0)
JSR PC,RLFREE
CCC
RTS PC
; relative jumps: RFRCHK,RJMP,RJMPC
COMMENT ⊗ These routines are parallel to the jump and transfer of control
routines in AL. The relative jumps are needed to produce
position independent pcode for the bodies of procedures
⊗
RFRCHK: ; copied from FORCHK in INTRP.PAL
;Assume that the stack has, from surface in, the increment, the
; final value, and the control variable's value, all of which are
; scalar values. If (FINAL-CONVAR)*(INCREMENT) ≥ 0 then this is a
; no-op; otherwise, jump to the destination.
;Arguments: destination. ***** offset for control variable, destination *****
;****** MOV 4(R3),-(R3) ;Copy the control variable's value
;****** JSR PC,CHNGE ;Go update it
LDF @2(R3),AC0 ;AC0 ← final value
SUBF @4(R3),AC0 ;AC0 ← final - current
MULF @(R3),AC0 ;AC0 ← (final - current)*increment
FETCH R0 ;R0 ← destination offset ******** differs from FORCHK
ASL R0 ; to change to bytes
CFCC
BGE 1$ ;Shall this be a no-op?
BACKIPC ; since IPC is now pointing to next instruction
ADD R0,IPC(R4) ;No; set new IPC. ******* in FORCHK this is MOV
;****** ADD #6,R3 ;Pop the inc, final & control var off of the stack ****
1$: CLR R0
RTS PC ;Done
RJMP:
;Takes one argument: the relative offset of new address.
MOV @IPC(R4),R0 ; get the offset
ASL R0 ; change to bytes
ADD R0,IPC(R4) ; increment IPC by the offset
CCC ;Clear condition code.
RTS PC ;Done
RJMPC: ;Parallel to JUMPC in INTERP.PAL[AL,HE]
LDF @(R3)+,AC0 ;Get value of boolean
CFCC ;copy condition codes
BEQ 1$ ;if false succeed - take branch
BMPIPC ;skip over address
RTS PC ; & return
1$: MOV @IPC(R4),R0 ; get the offset
ASL R0 ; change to bytes
ADD R0,IPC(R4) ; branch
RTS PC ; & return
; printing routines: RPRINT,PRVAL,PRINTI
PRINTI: FETCH <-(SP)> ; string printing this will replace RPRINT
; (SP)←# of words to be printed
ASL (SP) ; convert to bytes
MOV @IPC(R4),R0 ; R0←starting address of string
ADD (SP)+,@IPC(R4) ; update the IPC
JMP PRINT0
RPRINT: MOV @IPC(R4),R0
ASL R0
ADD IPC(R4),R0 ; put absolute address into R0 of string
BMPIPC
JMP PRINT0
TACK:
COMMENT ⊗ R1 = LOC[ascie string to tack on], R0 = LOC[where to put
it]. Returns R0 ← next location available in destination string. ⊗
MOVB (R1)+,(R0)+;Copy a byte
BNE TACK ;Repeat while necessary
DEC R0 ;Go back past the null
RTS PC ;Done
.MACRO TACKST B ;tack the string B
MOV #B,R1
JSR PC,TACK
.ENDM
.MACRO TACKC B ;tack the character B
MOVB #B,(R0)+ ;move in the value
.ENDM
; following routines are used to get a different form for printing
; R0 will point to next place in the string
PRVAL: PUSH <R2> ;save R2
EVWAIT CSLEVT
MOV #4,R0
MOV #2,R1 ; set format parameters to 2 dec places and squueze out blanks
JSR PC,FORMAT ; use format to squeeze out blanks
FETCH <R1> ; get type of printing
ASH #1,R1 ; TIMES 2
MOV #OUTBUF,R0 ; set R0←start of buffer
JSR PC,@1$-2(R1); call appropriate routines to build up string
CLRB (R0) ; ensure last character is a null to get rid of garbage
MOV #OUTBUF,R0 ; now print it
JSR PC,TYPSTR
JSR PC,RSTFOR ; restore format
EVSIG CSLEVT
POP <R2> ; restore r2
CCC
RTS PC
DATA
1$: PRSCA
PRVEC
PRROT
PRTRN
PRFRM
CODE
PRSCA: MOV (R3)+,R2 ;R2←LOC[value cell]
PRREAL: LDF (R2)+,AC0
JSR PC,CVF ; go the conversion
RTS PC
PRVEC: MOV (R3)+,R2
PVECT: TACKST VNAMEL ; tack "VECTOR("
JSR PC,PRREAL ; tack first value
TACKC COMMA
JSR PC,PRREAL ; second value
TACKC COMMA
JSR PC,PRREAL ; third value
TACKC ') ;")"
RTS PC
PRROT: PUSH <R0>
MOV (R3)+,R0
MOV #EDAT,R1
JSR PC,EULER ; change to EULER angles
MOV #EDAT,R2 ; correct address for R2
POP <R0>
PROT: TACKST ROTZHC ; tack ROT(ZHAT,
JSR PC,PRREAL ; value
TACKC ')
TACKC '*
TACKST ROTYHC ; print ROT(YHAT,
JSR PC,PRREAL
TACKC ')
TACKC '*
TACKST ROTZHC ; print ROT(ZHAT,
JSR PC,PRREAL
TACKC ')
RTS PC
PRTRN: MOV #TNAMEL,R1 ; print "TRANS("
JMP PRFRM0
PRFRM: MOV #FNAMEL,R1 ; print "FRAME("
PRFRM0::JSR PC,TACK
JSR PC,PRROT ; use common code with PRROT to compute euler angles
; and tack the rot part
TACKC COMMA ; output a comma
JSR PC,PVECT ; print out the vector part
TACKC ') ; print out right paren
RTS PC
DATA
VNAMEL: .ASCIZ /VECT(/
TNAMEL:: .ASCIZ /TR(/
FNAMEL:: .ASCIZ /FR(/
ROTZHC:: .ASCIZ /ROT(Z,/
ROTYHC:: .ASCIZ /ROT(Y,/
.EVEN
CODE
; supplementary motions: pmove,tadrive,tddrive,gather,rforce,setstf
RPMOVE: MOV LRPMOVE,R2 ;set for position independent pcode
JMP MOVSTA ; used to be MOVST2
RTADRIVE: ; absolute drive
MOV LRTADRIVE,R2
JMP MOVSTA ; used to be MOVST2
RTDDRIVE: ; relative drive
MOV LRTDDRIVE,R2
JMP MOVSTA ; used to be MOVST2
RCENTER:
MOV LRCENTER,R2
JMP MOVSTA ; used to be MOVST2
COMMENT ⊗ used to return numbers for move
also uncomment pg 19 ln 99 of interp.pal
MOVST2: MOV #XMOVE,@INTPTR ;code for move
MOV INTPTR,SVPTR ;save the current pointer
ADD #2,INTPTR ;increment pointer
MOV INTPTR,-(SP) ;save the pointer
CLR RPFLAG ;clear the retry flag
JSR PC,MOVSTA ;perform the motion
TST RPFLAG ;did we go through a retry?
BNE 2$ ;yes, we did
CMP INTPTR,(SP)+ ;no, satisfactory move(check if move incremented
;pointers
BNE 1$ ;yes, don't add anything
CLR @INTPTR ;no, clear next two words
ADD #2,INTPTR
CLR @INTPTR
ADD #2,INTPTR
1$: RTS PC ;return
2$: MOV SVPTR,INTPTR ;we went through a retry, back up
TST (SP)+ ;pop the stack
RTS PC
DATA
SVPTR: 0 ;used in case we do a RETRY$G
RPFLAG: 0 ;checks if we did a RETRY$G
CODE
⊗ ;
GATHER: FETCH <R0>
MOV #FPPTR,R1 ;address of FP buffer
MOV #INTPTR,R2 ;address of INTEGER buffer
JSR PC,@LGATHER ; now go call the appropriate routine
RTS PC
RFORCE: SNDINT #XRFORCE ;send back a xrforce
MOV #INTPTR,R1 ;address of integer buffer
JSR PC,@LRFORCE
CCC
RTS PC
SETSTF: MOV (R3)+,-(SP) ; save trans address
MOV #1$+24.,R0 ; address of arguments
MOV #6,R1 ; six of them
2$: LDF @(R3)+,AC0 ; get the argument
STF AC0,-(R0) ; put in the right place
SOB R1,2$
; MOV #1$,R0 ; let R0 point to the right place
; R0 will be pointing to the right place
MOV (SP)+,R1 ; R1 has address of trans
JSR PC,@LSETSTF ; jump into the arm code
CCC
RTS PC ; and return
DATA
1$: .BLKW 12. ; space for 6 real numbers
CODE
; supplementary functions: uparrow,dwnarrow,alpha,dollar,swap,vneg,vsmul,ftof
UPARROW: MOV #ZHAT,-(R3) ; ↑ z-axis pointing upward, current frame or trans
MOV 2(R3),R0 ; get original trans value
LDF (R0),AC0
MULF AC0,AC0 ; (1,1)↑2
LDF 4(R0),AC1
MULF AC1,AC1 ; (2,1)↑2
ADDF AC1,AC0 ; ACO←(1,1)↑2+(2,1)↑2
CMPF C0001,AC0 ; If AC0<C001 skip ahead
CFCC
BGT 1$
CLRF AC0
SUBF 10(R0),AC0 ; -(3,1)
JSR PC,@LASIN ; take arc-sin
BR 2$
1$: LDF 34(R0),AC0
LDF 30(R0),AC1
JSR PC,@LATAN2 ; take arc-tan2( (2,3),(1,3))
2$: JSR PC,GETSCA ;R0 ← -(R3) ← LOC[new scalar block]
STF AC0,@(R3) ;Store result
BR DW3 ;produce the rot
DOLLAR: MOV #NILROT,-(R3) ; $ station orientation, i.e. nilrot
BR DW2
ALPHA: MOV #ZHAT,-(R3) ; bgrasp orien at bpark, e.e. rot(zhat,180)
BR DW1
DWNARROW: MOV #YHAT,-(R3) ; ↓ bpark orien, i.e. rot(yhat,180)
DW1: MOV #F180,-(R3) ; rot of 180 deg
DW3: JSR PC,VSAXWR ; return rot(vect,180) on stack
DW2: JSR PC,SWAP ; turn the top two elements around
JSR PC,TPOS ; take the position value of previous frame
JSR PC,TMAKE ; produce the transform
RTS PC ; and return
VNEG: MOV (R3),-(R3) ; copy the vector on the stack
MOV #NILVEC,2(R3) ; put in nilvector
JMP VSUB
VSMUL: JSR PC,SWAP ; reverse the two top elements
JMP SVMUL ; exit from SVMUL
SWAP: MOV (R3),-(SP) ; switch positions of top two elementsof stack
MOV 2(R3),(R3)
MOV (SP)+,2(R3)
RTS PC
WRT: JSR PC,TORIEN ; v wrt t = orient(t)*v
VFREL: JSR PC,SWAP ; v rel f = t*v
JMP TVMUL
FTOF: JSR PC,SWAP ;t1→t2 = inv(t1)*t2
JSR PC,TINVRT
FFREL: JSR PC,SWAP ; f rel t = t*f
JMP TTMUL
; take positions of three frames and put them
; to the stack
FCONSTR: MOV (R3)+,-(SP) ; save top two elements
MOV (R3)+,-(SP)
JSR PC,TPOS ; find position of frame 1
MOV (SP)+,-(R3)
JSR PC,TPOS ; find position of frame 2
MOV (SP)+,-(R3)
JSR PC,TPOS ; find position of frame 3
JMP CONSTR
; functions: sqrt,sin,cos,asin,acos,tan,atan2,log,exp
PSQRT: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,SQRT
JMP SRET
PSIN: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,SIN
JMP SRET
PCOS: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,COS
JMP SRET
PTAN: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,TAN
JMP SRET
PASIN: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,ASIN
JMP SRET
PACOS: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,ACOS
JMP SRET
PATAN2: JSR PC,SWAP
LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,ATAN2
JMP SRET
PLOG: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,LOG
JMP SRET
PEXP: LDF @(R3)+,AC0 ;AC0 ← arg
JSR PC,EXP
JMP SRET
; armreach- can arm reach here?
; routine checks if arm can reach location specified on the stack
; it leaves true or false on the stack
ARMREACH:
PUSH <R2> ; save R2
MOV #28.,R0 ; angle list
JSR PC,GTFREE
PUSH <R0>
MOV #14.,R0
JSR PC,GTFREE ; pointer list
PUSH <R0>
MOV 2(SP),R1 ;R1←address of angle values
MOV #14.,R2 ; shift 14 addresses
1$: MOV R1,(R0)+
ADD #4,R1
SOB R2,1$
MOV (R3)+,R0 ;R0←LOC[trans]
MOV (SP),R1 ;R1←address pointers
FETCH <R2> ;R2←mechanism
;;; JSR PC,LSOLVE ; jump into armsolution routine
PUSH <R0> ; save error code
JSR PC,GETSCA ; R0←-(R3)←LOC[scalar]
MOV ONE,(R0)+ ; put scalar as true
CLR (R0)
TST (SP)+ ; check error code from SOLVE
BEQ 2$ ; there was no error
CLR (R3) ; oops there was an error
2$: POP <R0>
JSR PC,RLFREE ; release theta pointer space
POP <R0>
JSR PC,RLFREE ; release space for theta angles
POP <R2> ; restore R2
CCC
RTS PC ; return
; procedure handling: GTBLK
GTBLK:
COMMENT ⊗
GTBLK n ..... q
n is size of the block of pcode to be copied
..... is n words of information
the address of the block is to be put at the location of q + offset q
⊗
FETCH <R0> ; get size of the block to get
MOV R0,R2 ;
; ADD R0,R0 ; get size in bytes
JSR PC,GTFREE ; get the size we need
MOV R0,-(SP) ; save the address of the block
1$: FETCH <R1> ; get word to transfer
MOV R1,(R0)+ ; transfer to new area
SOB R2,1$
MOV @IPC(R4),R1 ; now get the offset in which to stick the address of this block
ASL R1 ; get it in bytes
ADD IPC(R4),R1 ; get the absolute address
BMPIPC
MOV (SP)+,(R1) ; write into the pcode ####### ... careful !
RTS PC ; and return
; more stack ops: gtint,gvals,chngs
APUSHOFFSET:
JSR PC,PUSHINITI ; push index onto stack
PUSHOFFSET:
AREF:
; The argument is an integer. Make a scalar record and store the offset value
; on that stack.
; this routine is used in conjunction with GVALS and CHNGS
JMP PUSHINTI
GTINT: LDF @(R3)+,AC0 ;Get value of top element of stack
STCFI AC0,R0 ;Convert it to integer & store it in R0
RTS PC
GVALS: JSR PC,GTINT ; get the value of variable whose offset is on stack
JMP GVAL0
CHNGS: JSR PC,GTINT ; change the value of the variable whose offset is on stack
JMP CHNG0
GTARGS: JSR PC,GTINT ; take the value from the stack and convert to integer
JMP GETARG
DATA
HLTMSG: 0
CODE
; components of data types: CHCMP,GTCMP
; appropriate component of element whose level offset is on stack is changed
; or obtained
CHCMP: FETCH <R0>
DEC R0 ;reduce by 1
ASH #2,R0 ;multiply by 4
MOV R0,-(SP)
JSR PC,GTARGS ; R0←[env entry]
MOV R0,-(SP) ; save for later use
JSR PC,GVAL1 ; (R3)←LOC[vect or trans]
MOV (R3),R0
CMPB #VCTID,TAGID(R0); check if it is a vector
BEQ 1$ ; yes it is
ADD #44,2(SP) ; no, it isnt
1$: JSR PC,SWAP ; trade two top elements of stack so scalar on top
LDF @(R3)+,AC0 ; AC0← value of component to be changed
MOV 2(SP),R0 ; put component into R0
ADD (R3),R0 ; get effective address of component
STF AC0,(R0) ; (R3) has appropriate value
MOV (SP)+,R0 ; get back environment entry
JSR PC,CHNG1 ; and change the value
TST (SP)+ ; pop the stack
RTS PC
CHTPOS: JSR PC,GVALS
MOV #44,R0 ; put the offset into R0
ADD (R3)+,R0 ; R0←LOC[x-comp of trans]
MOV (R3)+,R1 ; R1←LOC[x-comp of vector]
PUSH <R2>
MOV #3,R2 ; use R2 as counter
1$: LDF (R1)+,AC0
STF AC0,(R0)+
SOB R2,1$
POP <R2>
RTS PC
CHTORIENT:
JSR PC,GVALS
MOV (R3)+,R0 ;R0←[LOC trans]
MOV (R3)+,R1
PUSH <R2> ;use R2 as counter
MOV #9.,R2 ;transfer 9 elements
1$: LDF (R1)+,AC0
STF AC0,(R0)+
SOB R2,1$
POP <R2>
RTS PC
GTXC: CLR -(SP)
BR GTCMP0
GTYC: MOV #4,-(SP)
BR GTCMP0
GTZC: MOV #10,-(SP)
GTCMP0::MOV (R3),R0
ADD (R3)+,(SP) ; save on the stack
CMPB #VCTID,TAGID(R0); is it a vector?
BEQ 1$ ; yes, it is
ADD #44,(SP) ; no, it is a trans
1$: JSR PC,NOCMP ;dont compact for a bit
JSR PC,GETSCA ; R0←(R3)←LOC(scalar)
MOV (SP)+,R1 ; r1←LOC[element]
LDF (R1),AC0
STF AC0,(R0) ;get the appropriate value
JSR PC,YESCMP ;allow compacting
RTS PC
; return from POINTY : pdone
PDONE:
MOV RF,SP ;Restore stack
MOV -2(SP),RF ;RF ← old PC
RTS RF ;Just return